package com.rent.controller;

import cn.hutool.core.collection.CollectionUtil;
import com.rent.annotation.NoAuth;
import com.rent.beans.Result;
import com.rent.beans.dto.NearbyGeoDTO;
import com.rent.beans.resp.HouseListResp;
import com.rent.constants.SysConstant;
import com.rent.entity.House;
import com.rent.service.HouseService;
import com.rent.utils.RedisGeoUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.geo.Circle;
import org.springframework.data.geo.Distance;
import org.springframework.data.geo.Metrics;
import org.springframework.data.geo.Point;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author lihaoyang
 * @date 2021/6/8
 */
@Slf4j
@RequestMapping("/home")
@RestController
public class HomeController {

    @Autowired
    HouseService houseService;

    @Autowired
    RedisGeoUtil redisGeoUtil;

//    @Autowired
//    RedisUtil redisUtil;

    @NoAuth
    @GetMapping("/nearby")
    public Result nearbyHouse(@RequestParam String lat,
                               @RequestParam String lng,
                               @RequestParam(required = false,defaultValue = "5") Integer dist){
        log.info("HomeController#nearby,param lat:[{}],lng:[{}],dist:[{}]",lat,lng,dist);
        if(Objects.isNull(dist)){
            dist = 50;
        }

        Point point = new Point(Double.valueOf(lng),Double.valueOf(lat));
        Distance distance = new Distance(dist,Metrics.KILOMETERS);
        Circle circle = new Circle(point,distance);

        RedisGeoCommands.GeoRadiusCommandArgs args = RedisGeoCommands.GeoRadiusCommandArgs
                .newGeoRadiusArgs()
                .includeDistance()//距离
                .includeCoordinates()
                .sortAscending()//按距离排序
                .limit(100);

        List<NearbyGeoDTO> housePos = redisGeoUtil.nearByXY(SysConstant.HOUSE_GEO_PREFIX, circle, args);
        log.info("nearbyHouse#housePos:[{}]",housePos);
        if(CollectionUtil.isEmpty(housePos)){
            return Result.OK(Collections.emptyList());
        }
        //查询房子其他信息
        List<Integer> houseIds = housePos.stream().map(NearbyGeoDTO::getHouseId).collect(Collectors.toList());
        log.info("houseIds:[{}]",houseIds);
        Map<Integer, Double> distanceMap = housePos.stream().collect(Collectors.toMap(NearbyGeoDTO::getHouseId, NearbyGeoDTO::getDistince, (k1, k2) -> k1));
        List<House> houseList = houseService.findByHouseIdList(houseIds);
        List<HouseListResp> resultList = new ArrayList<>();
        for(House house : houseList){
            HouseListResp resp = new HouseListResp(house);
            resp.setDistance(String.valueOf(distanceMap.get(house.getId())));
            resultList.add(resp);
        }

        return Result.OK(resultList);
    }

//    @NoAuth
//    @GetMapping("/redisSet")
//    public Result redisSet(String key,String value){
//        return Result.OK(redisUtil.set(key,value));
//    }
//
//    @NoAuth
//    @GetMapping("/redisGet")
//    public Result redisGet(String key){
//        return Result.OK(redisUtil.get(key));
//    }
}
